<!DOCTYPE HTML>
<html>
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="utf-8">
  
  <title>Java对象的创建 › 但行好事，莫问前程</title>
  <meta name="author" content="fengbo">
  
  <meta name="description" content="不想当架构师的程序员不是好厨师 ，不认为PHP是世界上最好的编程语言的Python开发者不是一个好的Javaer。">
  
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  <meta property="og:title" content="Java对象的创建">
  <meta property="og:site_name" content="但行好事，莫问前程">

  
    <meta property="og:image" content="undefined">
  

  <link href="/favicon.png" rel="icon">
  <link rel="alternate" href="/atom.xml" title="但行好事，莫问前程" type="application/atom+xml">
  <link rel="stylesheet" href="/css/style.css" media="screen" type="text/css">
  <!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
  

</head>
</html>

<body>
  <header id="header"><div class="meta inner">
  <h1><a href="/">但行好事，莫问前程</a></h1>
  <h2><a href="/">CV工程师，了解面向Google编程的基本原理，有三年使用Google经验，在通往程序员的道路上艰难的爬行着。</a></h2>
  <nav id="main-nav">
    <ul>
      
      <li><a href="/">Home</a></li>
      
      <li><a href="/archives">Archives</a></li>
      
      <li><a href="/atom.xml">RSS</a></li>
      
    </ul>
    <div class="clearfix"></div>
  </nav>
</div>
<div class="clearfix"></div>
</header>
  <div id="content" class="inner">
    <div id="main-col" class="alignleft"><div id="wrapper"><article class="post">
  <div class="post-content">
    <header>
      
  
    <h1 class="title">Java对象的创建</h1>
  

      
        <time datetime="2017-10-18T13:03:58.000Z">2017-10-18</time>
      
    </header>
    <div class="entry">
      
        <h2 id="对象创建时机"><a href="#对象创建时机" class="headerlink" title="对象创建时机"></a>对象创建时机</h2><ul>
<li>使用new关键字创建对象；</li>
<li>使用反射创建对象：即使用Class类的newInstance方法、Constructor类的newInstance方法等创建对象；</li>
<li>使用Clone方法创建一个对象：无论何时我们调用一个对象的clone方法，JVM都会帮助我们创建一个新的、一样的对象，且该对象的创建过程中并不会调用任何构造函数。</li>
<li>使用反序列化机制创建对象：当我们反序列化一个对象时，JVM会给我们创建一个单独的对象，且JVM并不会调用任何构造函数。<a id="more"></a>
</li>
</ul>
<h2 id="对象的创建过程"><a href="#对象的创建过程" class="headerlink" title="对象的创建过程"></a>对象的创建过程</h2><ol>
<li>类加载：虚拟机遇到new指令时，根据这个指令的参数去常量池中定位一个类的符号引用。并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有那必须先执行相应的类加载过程。</li>
<li>内存分配：对象所需要的内存大小在类加载完成后便可以直接确定，为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。</li>
<li>初始化：内存分配完成后，虚拟机需要将分配到的内存空间都初始化为零值（不包括对象头）。</li>
<li>虚拟机对对象进行必要的设置，例如这个对象是哪个类的实例、如果才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象头中。根据虚拟机当前的运行状态不同，如是否设置偏向锁等，对象头会有不同的设置方式。</li>
<li>实例变量初始化和实例代码块初始化(<b>目前所有实例变量都还为零</b>)：在程序中可以直接对实例变量进行赋值或者使用实例代码块对其进行赋值。实际上使用上面两种方式编译器会将代码放到类的构造函数中去，并且这些代码会被放在对超类构造函数的调用语句之后，构造函数本身的代码之前。</li>
<li>执行＜init＞方法，把对象按照程序员的意愿进行初始化，即进行构造函数初始化。</li>
</ol>
<h2 id="进行内存分配的方法"><a href="#进行内存分配的方法" class="headerlink" title="进行内存分配的方法"></a>进行内存分配的方法</h2><ul>
<li>指针碰撞：假设Java堆中内存是绝对完规整的，所有用过的内存都放在一边，空闲的内存都放在另一边，中间放着一个指针作为分界点的指示器，那所分配的内存就仅仅是把那个指针向空闲空间挪动一段与对象大小相等的距离。</li>
<li>空闲列表：如果Java堆中的内存不是规整的，已使用的内存和空闲的内存相互交错，虚拟机需要维护一个列表，记录上哪些内存块是可用的，在分配内存的时候从列表中找到一块足够大的空间划分给对象实例，并更新列表上的记录。</li>
</ul>
<h2 id="进行内存分配时遇到的问题"><a href="#进行内存分配时遇到的问题" class="headerlink" title="进行内存分配时遇到的问题"></a>进行内存分配时遇到的问题</h2><ul>
<li>并发问题：即可能出现正在给对象A分配内存，指针还没来的及修改，对象B又同时使用了原来的指针来分配内存的问题。</li>
<li>解决办法 <ol>
<li>对内存空间的动作进行同步处理（实际上虚拟机采用CSA配上重试的方式保证更新操作的原子性）。</li>
<li>把内存分配的动作按照线程划分在不同的空间之中进行，即每个线程在Java堆中预先分配一块小的内存，成为本地线程分配缓冲（Thread Local Allocation Buffer TLAB），哪个线程分配内存，就在哪个线程的TLAB上分配，只有TLAB用完需要获取新的空间时（不常见），才需要同步锁定。</li>
</ol>
</li>
</ul>
<h2 id="对象的内存划分"><a href="#对象的内存划分" class="headerlink" title="对象的内存划分"></a>对象的内存划分</h2><h3 id="对象头"><a href="#对象头" class="headerlink" title="对象头"></a>对象头</h3><ol>
<li>存储对象自身的运行时数据，如哈希码（HashCode）、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等，这部分数据的长度在32位和64位的虚拟机（未开启压缩指针）中分别为32bit和64bit，官方称它为Mark Word；</li>
<li>存储类型指针，即对象指向方法区对象类型数据的指针，虚拟机通过这个指针来确定这个对象是哪个类的实例。如果是数组对象的话，还会额外存储数组的长度。</li>
</ol>
<h3 id="实例数据"><a href="#实例数据" class="headerlink" title="实例数据"></a>实例数据</h3><p>这部分存储的是对象的真正的有效信息，即程序代码中定义的各种类型的字段内容。</p>
<h3 id="对齐填充"><a href="#对齐填充" class="headerlink" title="对齐填充"></a>对齐填充</h3><p>HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍，对象头部分正好是8字节的倍数，因此，当对象实例数据部分不是8字节的整数倍时，就需要通过对齐填充来补全。</p>
<h2 id="栈对堆中的对象的访问定位"><a href="#栈对堆中的对象的访问定位" class="headerlink" title="栈对堆中的对象的访问定位"></a>栈对堆中的对象的访问定位</h2><p>Java程序需要通过栈上的引用数据来操作堆上的具体对象。由于引用类型在Java虚拟机规范中值规定了一个指向对象的引用，并没有定义这个引用应该通过何种方式去定位、访问堆中的对象的具体位置，所有对象访问方式取决于虚拟机实现。</p>
<ul>
<li>直接指针：栈中的引用类型存储的就是对象在堆上的地址。</li>
<li>使用句柄进行定位：Java堆中将会划分出一块内存来作为句柄池，栈中存储的就是对象的句柄地址。而句柄中包含了对象实例数据与类型数据各自的具体地址信息。</li>
</ul>
<h2 id="对象在堆中的分配与回收"><a href="#对象在堆中的分配与回收" class="headerlink" title="对象在堆中的分配与回收"></a>对象在堆中的分配与回收</h2><ol>
<li>如果启动了本地线程分配缓存，将按线程优先在TLAB上分配。而在大多数情况下，对象在新生代Eden区中分配。当该区中没有足够的空间进行分配时，虚拟机将进行一次Minor GC。虚拟机提供了-XX:+PrintGCDetails这个收集器日志参数，告诉虚拟机在发生垃圾收集行为是打印回收日志。</li>
<li>对象在Eden出生并经过第一次Minor GC后仍然存活，并且能被Survivor容纳的话，将被移动到Survivor空间中，并且对象年龄设为1。Survivor又分为Form和To区，它们是两块一模一样的内存区域；即使用复制算法将每次Minor GC后仍然存活的对象移动到另一端，然后清空该区域。</li>
</ol>
<h3 id="对象进入老年代的条件"><a href="#对象进入老年代的条件" class="headerlink" title="对象进入老年代的条件"></a>对象进入老年代的条件</h3><ul>
<li>大对象直接在老年代初始化，大对象是指需要大量连续内存空间的Java对象，最典型的大对象就是那种很长的字符串以及数组。大于-XX:PretenureSizeThreshold参数的值的对象直接在老年代分配。</li>
<li>对象在Survivor区中每活过一次Minor GC年龄+1，当它的年龄增加到一定程度（默认是15岁），就被移动到老年代中。可以通过参数-XX:MaxTenuringThreshold设置。</li>
<li>在Survivor区中相同年龄所有对象大小的总和大于Survivor空间的一半，年龄大于或等于该年龄的对象就可以直接进入老年代，无须等到MaxTenuringThreshold中要求的年龄。</li>
</ul>
<h3 id="空间分配担保"><a href="#空间分配担保" class="headerlink" title="空间分配担保"></a>空间分配担保</h3><ol>
<li>IBM公司的专门研究表明，新生代中的对象98%都活不过第一次垃圾回收，所以新生代中Eden空间远大于两块较小的Survivor空间，每次使用Eden和其中一块Survivor。当回收是，将Eden和Survivor中还存活的对象一次性复制到另一块Survivor空间上，然后清理掉Eden和刚刚用过的Survivor空间。HotSpot虚拟机默认Eden和Survivor比例是8:1。当Survivor空间不够用是，需要依赖其它内存进行分配担保。</li>
<li>在发生Minor GC之前，虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间，如果这个条件成立，那么Minor GC可用确保是安全的。不过不成立，则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许，那么会继续检查老年代最大可用连续空间是否大于历次晋升老年代对象的平均大小，如果大于，将尝试着进行一次Minor GC，尽管这才Minor GC是有风险的；如果小于或者HandlePromotionFailure设置值不允许冒险，那么就改为进行一次Full GC。</li>
<li>风险是指当Minor GC后仍然有大量的对象存活，Survivor无法容纳的对象需要直接进入老年代，如果老年代也没有足够的空间，还是需要一次Full GC。相当于多进行了一次Minor GC。</li>
</ol>

      
    </div>
      
      <footer>
        
        
  
  <div class="tags">
    <a href="/tags/Java高级特性/">Java高级特性</a>
  </div>

        
  <div class="addthis addthis_toolbox addthis_default_style">
    
      <a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
    
    
      <a class="addthis_button_tweet"></a>
    
    
      <a class="addthis_button_google_plusone" g:plusone:size="medium"></a>
    
    
      <a class="addthis_button_pinterest_pinit" pi:pinit:layout="horizontal"></a>
    
    <a class="addthis_counter addthis_pill_style"></a>
  </div>
  <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js"></script>

      
      <div class="clearfix"></div>
      </footer>
  </div>
</article>

<!-- 来必力City版安装代码 -->
<!-- <div id="lv-container" data-id="city" data-uid="MTAyMC8yOTQ5MS82MDU5">
<script type="text/javascript">
   (function(d, s) {
       var j, e = d.getElementsByTagName(s)[0];

       if (typeof LivereTower === 'function') { return; }

       j = d.createElement(s);
       j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
       j.async = true;

       e.parentNode.insertBefore(j, e);
   })(document, 'script');
</script>
<noscript>为正常使用来必力评论功能请激活JavaScript</noscript>
</div> -->
<!-- City版安装代码已完成 -->

</div></div>
    <aside id="sidebar" class="alignright">
  
<div class="widget tagcloud">
  <h3 class="title">文章分类</h3>
  <div class="entry">
    <a href="/tags/JavaWeb/" style="font-size: 17.14px;">JavaWeb</a> <a href="/tags/Java基础/" style="font-size: 15.71px;">Java基础</a> <a href="/tags/Java高级特性/" style="font-size: 15.71px;">Java高级特性</a> <a href="/tags/Python/" style="font-size: 10px;">Python</a> <a href="/tags/Spring基础/" style="font-size: 14.29px;">Spring基础</a> <a href="/tags/WebRTC/" style="font-size: 10px;">WebRTC</a> <a href="/tags/其它/" style="font-size: 20px;">其它</a> <a href="/tags/分布式/" style="font-size: 11.43px;">分布式</a> <a href="/tags/硬件/" style="font-size: 12.86px;">硬件</a> <a href="/tags/计算机基础/" style="font-size: 18.57px;">计算机基础</a> <a href="/tags/设计模式/" style="font-size: 17.14px;">设计模式</a>
  </div>
</div>



    <div class="widget tagcloud">
    <h3 class="title">电子书</h3>
    <ul class="entry">
      <li class='link'><a href='http://www.duokan.com/' target="_blank">多看阅读</a>&nbsp;&nbsp;<a href='https://read.douban.com/' target="_blank">豆瓣阅读</a>&nbsp;&nbsp;<a href='http://e.dangdang.com/' target="_blank">当当阅读</a></li>
      <li class='link'><a href='http://www.ituring.com.cn/' target="_blank">图灵社区</a>&nbsp;&nbsp;<a href='https://www.epubit.com/' target="_blank">异步社区</a>&nbsp;&nbsp;<a href='https://www.geekbang.org/' target="_blank">极客空间</a></li>
    </ul>
  </div>


  
  <div class="widget tag">
    <h3 class="title">友情链接</h3>
      <ul class="entry">
        
          <li class='link'><a href='http://www.cnblogs.com/jietang/' target="_blank">唐洁的博客</a></li>
        
          <li class='link'><a href='http://rednaxelafx.iteye.com/' target="_blank">R大的博客</a></li>
        
          <li class='link'><a href='http://www.hollischuang.com/' target="_blank">阿里大神的博客</a></li>
        
          <li class='link'><a href='http://blog.csdn.net/IT_faquir/' target="_blank">IT_faquir的专栏</a></li>
        
      </ul>
  </div>


  
  <div class="widget tag">
    <h3 class="title">思维导图</h3>
      <ul class="entry">
        
          <li class='link'><a href='https://fengbo4213.github.io/img/开源协议.png' target="_blank">开源协议简介</a></li>
        
          <li class='link'><a href='https://www.processon.com/diagraming/5b0cf757e4b009aef58d4b9d' target="_blank">我的知识体系</a></li>
        
          <li class='link'><a href='https://www.processon.com/view/link/5a2a00e5e4b015e677290b4f' target="_blank">简单的网站架构</a></li>
        
      </ul>
  </div>


  
  <div class="widget tag">
    <h3 class="title">在线手册</h3>
      <ul class="entry">
        
          <li class='link'><a href='http://v3.bootcss.com/' target="_blank">BootStrap官方手册</a></li>
        
          <li class='link'><a href='http://www.iconfont.cn/http://element.eleme.io/#/zh-CN/' target="_blank">阿里巴巴矢量图标库</a></li>
        
      </ul>
  </div>


  
<div class="widget tag">
  <h3 class="title">最新文章</h3>
  <ul class="entry">
    
      <li>
        <a href="/2123/08/30/基础之MySQL原理/">MySQL原理</a>
      </li>
    
      <li>
        <a href="/2024/01/01/其它之ClickHouse索引/">ClickHouse索引</a>
      </li>
    
      <li>
        <a href="/2023/12/17/其它之MySQL线程池/">MySQL线程池</a>
      </li>
    
      <li>
        <a href="/2023/12/16/其它之InnoDB性能优化基础/">InnoDB性能优化基础</a>
      </li>
    
      <li>
        <a href="/2023/12/03/其它之Java8之后的版本新特性/">Java8之后的版本新特性</a>
      </li>
    
  </ul>
</div>

</aside>
    <div class="clearfix"></div>
  </div>
  <footer id="footer" class="inner"><div class="alignleft">
  
  &copy; 2024 fengbo
  
</div>
<div class="clearfix"></div></footer>
  <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>



</body>
</html>

